package cn.yzj.openapi.utils;

import cn.yzj.openapi.basic.SecretShortUrl;
import cn.yzj.openapi.common.Common;
import org.springframework.util.StringUtils;

import java.util.Random;

/**
 * 地址处理工具
 *
 * @author gzkemays
 * @since 2021/11/11 16:48
 */
public class UrlOperaUtils {
  private static final String SHORT_URL_PREFIX = "http://open.yeziji.xyz/s/";
  private static final String BASE62 =
      "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  private static final Integer INSERT_CHAT_NUM = 6;

  /**
   * 生成短链接
   *
   * @param url 原地址
   * @return 短链接
   */
  public static SecretShortUrl generateShortUrl(String url) {
    SecretShortUrl shortUrl = createKey();
    shortUrl.setOriginUrl(url);
    shortUrl.setShortUrl(SHORT_URL_PREFIX + shortEnd(shortUrl.getKey()));
    return shortUrl;
  }

  /**
   * 生成密钥
   *
   * @return 密钥
   */
  public static SecretShortUrl createKey() {
    Random rand = new Random();
    StringBuilder sb = new StringBuilder();
    StringBuilder salt = new StringBuilder();
    for (int i = 0; i < INSERT_CHAT_NUM; i++) {
      char saltFragment =
          Common.SECRET_SALT
              .replaceAll("-", Common.EMPTY)
              .replaceAll("_", Common.EMPTY)
              .charAt(rand.nextInt(16));
      char keyFragment = BASE62.charAt(rand.nextInt(62));
      sb.append(keyFragment);
      if (i % 2 == 0) {
        sb.append(saltFragment);
      }
      salt.append(saltFragment);
    }
    return SecretShortUrl.builder()
        .salt(salt.toString())
        .key(encryption(sb.toString().toCharArray()))
        .build();
  }

  /**
   * 生成后缀
   *
   * @param key 密钥
   * @return 后缀值
   */
  public static String shortEnd(String key) {
    char[] a = key.toCharArray();
    for (int i = 0; i < a.length; i++) {
      a[i] = (char) (a[i] ^ 5);
    }
    char[] originKey = new String(a).toCharArray();
    for (int i = 1; i <= 3; i++) {
      int index = 3 * i - 2;
      originKey[index] = ' ';
    }
    return StringUtils.trimAllWhitespace(new String(originKey));
  }

  /**
   * 解密算法
   *
   * @param url 加密短链接
   * @param salt 盐值
   * @return 获得短链接对应的 key
   */
  public static String decryptShortUrl(String url, String salt) {
    String end = url.replaceFirst(SHORT_URL_PREFIX, Common.EMPTY);
    char[] endChars = end.toCharArray();
    char[] saltChars = salt.toCharArray();
    char[] tempChars = new char[endChars.length + 3];
    for (int i = 0; i < tempChars.length; i++) {
      if (i <= endChars.length) {
        switch (i) {
          case 0:
            tempChars[i] = endChars[0];
            break;
          case 1:
            tempChars[i] = saltChars[0];
            break;
          case 2:
          case 3:
            tempChars[i] = endChars[i - 1];
            break;
          case 4:
            tempChars[i] = saltChars[2];
            break;
          default:
            tempChars[i] = endChars[i - 2];
        }
      } else {
        tempChars[i] = i == 7 ? saltChars[i - 3] : endChars[i - 3];
      }
    }
    return encryption(tempChars);
  }

  /**
   * 加密算法
   *
   * @param chars 加密字符串
   * @return 加密结果
   */
  public static String encryption(char[] chars) {
    for (int i = 0; i < chars.length; i++) {
      chars[i] = (char) (chars[i] ^ 5);
    }
    return new String(chars);
  }
}
